package com.wrapp.floatlabelededittext;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Component;
import ohos.agp.components.TextField;
import ohos.agp.components.Text;
import ohos.agp.components.AttrSet;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;

import ohos.app.Context;

import static com.wrapp.floatlabelededittext.Constants.BLUE_COLOR_FOCUSED;
import static com.wrapp.floatlabelededittext.Constants.GREY_COLOR_NON_FOCUSED;
import static com.wrapp.floatlabelededittext.Constants.GREY_COLOR_HINT_NON_FOCUSED;

public class FloatLabeledEditText extends DirectionalLayout implements Component.DrawTask {
    private final Color mFocusedLineColor = new Color(Color.getIntColor(BLUE_COLOR_FOCUSED));

    private final Color mNonFocusedLineColor = new Color(Color.getIntColor(GREY_COLOR_NON_FOCUSED));

    private final Color mHintTextNonFocusedColor = new Color(Color.getIntColor(GREY_COLOR_HINT_NON_FOCUSED));

    private Text mHintTextView;
    private TextField mEditText;

    private Context mContext;

    private String fletPaddingAttr = "fletPadding";

    private String fletPaddingLeftAttr = "fletPaddingLeft";

    private String fletPaddingTopAttr = "fletPaddingTop";

    private String fletPaddingRightAttr = "fletPaddingRight";

    private String fletPaddingBottomAttr = "fletPaddingBottom";

    private String fletBackgroundAttr = "fletBackground";

    private String fletTextAppearanceAttr = "fletTextAppearance";

    private int padding;

    private int paddingLeft = 0;

    private int paddingTop = 0;

    private int paddingRight = 0;

    private int paddingBottom = 0;

    private String hint;

    private String setHint = "";

    private ShapeElement mLineShapeElement;

    private Color mHintTextFocusedColor = new Color(Color.getIntColor("#505050"));

    private RgbColor mHintTextBackgroundColor = new RgbColor();

    public FloatLabeledEditText(Context context) {
        super(context);
        mContext = context;
        mHintTextView = new Text(mContext);
    }

    public FloatLabeledEditText(Context context, AttrSet attrSet) {
        super(context, attrSet);
        mContext = context;
        mHintTextView = new Text(mContext);
        addDrawTask(this);
        setAttributes(attrSet);
    }

    public FloatLabeledEditText(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        mContext = context;
        mHintTextView = new Text(mContext);
        setAttributes(attrSet);
    }

    private void setAttributes(AttrSet attrs) {
        mLineShapeElement = new ShapeElement();
        boolean isFletPaddingAttrPresent = attrs.getAttr(fletPaddingAttr).isPresent();
        if (isFletPaddingAttrPresent) {
            padding = Integer.parseInt(attrs.getAttr(fletPaddingAttr)
                    .get().getStringValue().trim().replaceAll("([a-z])", ""));
        }

        boolean isFletPaddingLeftAttrPresent = attrs.getAttr(fletPaddingLeftAttr).isPresent();
        if (isFletPaddingLeftAttrPresent) {
            paddingLeft = Integer.parseInt(attrs.getAttr(fletPaddingLeftAttr)
                    .get().getStringValue().trim().replaceAll("([a-z])", ""));
        }

        boolean isFletPaddingRightAttrPresent = attrs.getAttr(fletPaddingRightAttr).isPresent();
        if (isFletPaddingRightAttrPresent) {
            paddingRight = Integer.parseInt(attrs.getAttr(fletPaddingRightAttr)
                    .get().getStringValue().trim().replaceAll("([a-z])", ""));
        }

        boolean isFletPaddingTopAttrPresent = attrs.getAttr(fletPaddingTopAttr).isPresent();
        if (isFletPaddingTopAttrPresent) {
            paddingTop = Integer.parseInt(attrs.getAttr(fletPaddingTopAttr)
                    .get().getStringValue().trim().replaceAll("([a-z])", ""));
        }

        boolean isFletPaddingBottomAttrPresent = attrs.getAttr(fletPaddingBottomAttr).isPresent();
        if (isFletPaddingBottomAttrPresent) {
            paddingBottom = Integer.parseInt(attrs.getAttr(fletPaddingBottomAttr)
                    .get().getStringValue().trim().replaceAll("([a-z])", ""));
        }

        boolean isFletBackgroundAttrAttrPresent = attrs.getAttr(fletBackgroundAttr).isPresent();
        if (isFletBackgroundAttrAttrPresent) {
            Color backgroundColor = attrs.getAttr(fletBackgroundAttr).get().getColorValue();
            mHintTextBackgroundColor = RgbColor.fromArgbInt(backgroundColor.getValue());
        }else {
            mHintTextBackgroundColor = RgbColor.fromArgbInt(Color.TRANSPARENT.getValue());
        }

        boolean isFletTextAppearanceAttrPresent = attrs.getAttr(fletTextAppearanceAttr).isPresent();
        if (isFletTextAppearanceAttrPresent) {
            String backgroundHintColor = attrs.getAttr(fletTextAppearanceAttr).get().getStringValue().trim();
            int background = Color.getIntColor(backgroundHintColor);
            mHintTextFocusedColor = new Color(background);
        }

        if (padding != 0) {
            mHintTextView.setPadding(padding, padding, padding, padding);
        } else {
            mHintTextView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
        }

        //Start hidden
        mHintTextView.setVisibility(INVISIBLE);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        initChildComponents();
    }

    private void initChildComponents() {
        mEditText = (TextField) getComponentAt(0);
        hint = mEditText.getHint();

        DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(
                DirectionalLayout.LayoutConfig.MATCH_PARENT, DirectionalLayout.LayoutConfig.MATCH_PARENT,
                LayoutAlignment.START, 1);
        mHintTextView.setLayoutConfig(layoutConfig);

        removeComponentAt(0);
        addComponent(mHintTextView);
        addComponent(mEditText);

        mEditText.setMinHeight(100);
        mEditText.setTextSize(100);
        mEditText.setPaddingBottom(100);
        mEditText.setMultipleLine(false);

        mLineShapeElement.setShape(ShapeElement.LINE);
        mLineShapeElement.setStroke(10, RgbColor.fromArgbInt(mNonFocusedLineColor.getValue()));

        mEditText.setBackground(mLineShapeElement);

        setEditText();
    }

    private void setEditText() {
        if(this.setHint.equalsIgnoreCase("")){
            mHintTextView.setText(hint);
        }else {
            mHintTextView.setText(setHint);
            mEditText.setHint(setHint);
        }

        mEditText.addTextObserver(new Text.TextObserver() {
            @Override
            public void onTextUpdated(String value, int start, int before, int count) {
                if (value.equalsIgnoreCase("")) {
                    mHintTextView.setVisibility(INVISIBLE);
                } else {
                    mHintTextView.setVisibility(VISIBLE);
                    if(setHint.equalsIgnoreCase("")){
                        mHintTextView.setText(hint);
                    }else {
                        mHintTextView.setText(setHint);
                        mEditText.setHint(setHint);
                    }
                }
            }
        });

        mEditText.setFocusChangedListener(new FocusChangedListener() {
            @Override
            public void onFocusChange(Component component, boolean gotFocus) {
                onFocusChanged(gotFocus);
            }
        });
    }

    private void onFocusChanged(boolean gotFocus) {
        if (gotFocus) {
            mHintTextView.setTextColor(mHintTextFocusedColor);
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(mHintTextBackgroundColor);
            mHintTextView.setBackground(shapeElement);
            mLineShapeElement.setStroke(10, RgbColor.fromArgbInt(mFocusedLineColor.getValue()));
        } else {
            mHintTextView.setTextColor(mHintTextNonFocusedColor);
            mLineShapeElement.setStroke(10, RgbColor.fromArgbInt(mNonFocusedLineColor.getValue()));
        }
        mEditText.setBackground(mLineShapeElement);
    }

    public TextField getEditText() {
        return mEditText;
    }

    public void setHint(String hint) {
        this.setHint = hint;
    }

    public String getHint() {
        return mHintTextView.getText();
    }
}
